package com.clp.protocol.modbus_tcp.connect;

import com.clp.protocol.modbus_tcp.client.async.callback.RecvMbFrmCallback;
import com.clp.protocol.modbus_tcp.connect.config.ConnConfig;
import com.clp.protocol.modbus_tcp.mb_frame.ReqMbFrm;
import com.clp.protocol.modbus_tcp.mb_frame.RespMbFrm;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.Vector;

@Slf4j
public abstract class ConnInfoImpl implements ConnInfo {
    protected volatile Channel channel;
    protected final String remoteHost;
    protected final int remotePort;
    protected final int addr; // 公共地址验证

    // 回调列表
    protected final Vector<RecvMbFrmCallback> recvMbFrmCallbacks;

    protected ConnInfoImpl(Channel channel, ConnConfig cfg) {
        this.channel = channel;
        this.remoteHost = cfg.getRemoteHost();
        this.remotePort = cfg.getRemotePort();
        this.addr = cfg.getAddr();
        this.recvMbFrmCallbacks = new Vector<>();
    }

    /**
     * 重置
     * @param channel 通道
     */
    public void reset(Channel channel) {
        InetSocketAddress ipSocket = (InetSocketAddress) channel.remoteAddress();
        if ((this.remoteHost != null && !this.remoteHost.equals(ipSocket.getHostString()))
                || (this.remotePort != ipSocket.getPort())) {
            throw new RuntimeException("不能重置为不同ip:port的连接！");
        }
        this.channel = channel;

        // 不清空回调
    }

    public Channel channel() {
        if (!isConnected()) throw new RuntimeException("Channel未连接！");
        return channel;
    }

    @Override
    public boolean isConnected() {
        return channel != null && channel.isOpen() && channel.isActive();
    }

    @Override
    public String remoteHost() {
        return remoteHost;
    }

    @Override
    public int remotePort() {
        return remotePort;
    }

    @Override
    public int addr() {
        return addr;
    }

    protected RespMbFrm updateConnStatesByRecving(RespMbFrm respMbFrm) {
        return respMbFrm;
    }

    protected ReqMbFrm updateConnStatesBySending(ReqMbFrm reqMbFrm) {
        return reqMbFrm;
    }
}
